<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>如果有口音 | Elasticsearch: 权威指南 | Elastic</title>
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
</head>
<body>
<div class="main-container">
    <section id="content">
        
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原文地址: <a href="https://www.elastic.co/guide/cn/elasticsearch/guide/current/asciifolding-token-filter.html" rel="nofollow">https://www.elastic.co/guide/cn/elasticsearch/guide/current/asciifolding-token-filter.html</a>, 版权归 www.elastic.co 所有<br/>
                            英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/asciifolding-token-filter.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/asciifolding-token-filter.html</a>
                            </div>
                        <!-- start body -->
                  <div class="page_header">
<b>请注意:</b><br>本书基于 Elasticsearch 2.x 版本，有些内容可能已经过时。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: 权威指南</a></span>
»
<span class="breadcrumb-link"><a href="languages.html">处理人类语言</a></span>
»
<span class="breadcrumb-link"><a href="token-normalization.html">归一化词元</a></span>
»
<span class="breadcrumb-node">如果有口音</span>
</div>
<div class="navheader">
<span class="prev">
<a href="lowercase-token-filter.html">« 举个例子</a>
</span>
<span class="next">
<a href="unicode-normalization.html">Unicode的世界 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="asciifolding-token-filter"></a>如果有口音<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/220_Token_normalization/20_Removing_diacritics.asciidoc">edit</a>
</h2>
</div></div></div>
<p>英语用变音符号(例如 <code class="literal">´</code>, <code class="literal">^</code>, 和 <code class="literal">¨</code>) 来强调单词—​例如 <code class="literal">rôle</code>, <code class="literal">déjà</code>, 和 <code class="literal">däis</code> —​但是是否使用他们通常是可选的.  其他语言则通过变音符号来区分单词。当然，只是因为在你的索引中拼写正确的单词并不意味着用户将搜索正确的拼写。
去掉变音符号通常是有用的，让 <code class="literal">rôle</code> 对应 <code class="literal">role</code>, 或者反过来。 对于西方语言，可以用 <code class="literal">asciifolding</code> 字符过滤器来实现这个功能。  实际上，它不仅仅能去掉变音符号。它会把Unicode字符转化为ASCII来表示:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<code class="literal">ß</code> ⇒ <code class="literal">ss</code>
</li>
<li class="listitem">
<code class="literal">æ</code> ⇒ <code class="literal">ae</code>
</li>
<li class="listitem">
<code class="literal">ł</code> ⇒ <code class="literal">l</code>
</li>
<li class="listitem">
<code class="literal">ɰ</code> ⇒ <code class="literal">m</code>
</li>
<li class="listitem">
<code class="literal">⁇</code> ⇒ <code class="literal">??</code>
</li>
<li class="listitem">
<code class="literal">❷</code> ⇒ <code class="literal">2</code>
</li>
<li class="listitem">
<code class="literal">⁶</code> ⇒ <code class="literal">6</code>
</li>
</ul>
</div>
<p>像 <code class="literal">lowercase</code> 过滤器一样,  <code class="literal">asciifolding</code> 不需要任何配置，可以被 <code class="literal">custom</code> 分析器直接使用:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "folding": {
          "tokenizer": "standard",
          "filter":  [ "lowercase", "asciifolding" ]
        }
      }
    }
  }
}

GET /my_index?analyzer=folding
My œsophagus caused a débâcle <a id="CO140-1"></a><i class="conum" data-value="1"></i></pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO140-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>得到的词元 <code class="literal">my</code>, <code class="literal">oesophagus</code>, <code class="literal">caused</code>, <code class="literal">a</code>, <code class="literal">debacle</code></p>
</td>
</tr>
</table>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_保留原意"></a>保留原意<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/220_Token_normalization/20_Removing_diacritics.asciidoc">edit</a>
</h3>
</div></div></div>
<p>理所当然的，去掉变音符号会丢失原意。
例如, 参考 这三个 西班牙单词:</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">esta</code>
</span>
</dt>
<dd>
形容词 <em>this</em> 的阴性形式, 例如 <em>esta silla</em> (this chair) 和 <em>esta</em> (this one).
</dd>
<dt>
<span class="term">
<code class="literal">ésta</code>
</span>
</dt>
<dd>
<code class="literal">esta</code> 的古代用法.
</dd>
<dt>
<span class="term">
<code class="literal">está</code>
</span>
</dt>
<dd>
动词 <em>estar</em> (to be) 的第三人称形式, 例如 <em>está feliz</em> (he is happy).
</dd>
</dl>
</div>
<p>通常我们会合并前两个形式的单词，而去区分和他们不相同的第三个形式的单词。类似的:</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">sé</code>
</span>
</dt>
<dd>
动词 <em>saber</em> (to know) 的第一人称形式 例如 <em>Yo sé</em>  (I know).
</dd>
<dt>
<span class="term">
<code class="literal">se</code>
</span>
</dt>
<dd>
与许多动词使用的第三人称反身代词, 例如 <em>se sabe</em> (it is known).
</dd>
</dl>
</div>
<p>不幸的是，没有简单的方法，去区分哪些词应该保留变音符号和哪些词应该去掉变音符号。而且很有可能，你的用户也不知道.</p>
<p>相反， 我们对文本做两次索引: 一次用原文形式，一次用去掉变音符号的形式:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT /my_index/_mapping/my_type
{
  "properties": {
    "title": { <a id="CO141-1"></a><i class="conum" data-value="1"></i>
      "type":           "string",
      "analyzer":       "standard",
      "fields": {
        "folded": { <a id="CO141-2"></a><i class="conum" data-value="2"></i>
          "type":       "string",
          "analyzer":   "folding"
        }
      }
    }
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO141-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>在 <code class="literal">title</code> 字段用 <code class="literal">standard</code> 分析器，会保留原文的变音符号.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO141-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>在 <code class="literal">title.folded</code> 字段用 <code class="literal">folding</code> 分析器，会去掉变音符号</p>
</td>
</tr>
</table>
</div>
<p>你可以使用 <code class="literal">analyze</code> API 分析 <em>Esta está loca</em> (This woman is crazy)这个句子，来验证字段映射:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">GET /my_index/_analyze?field=title <a id="CO142-1"></a><i class="conum" data-value="1"></i>
Esta está loca

GET /my_index/_analyze?field=title.folded <a id="CO142-2"></a><i class="conum" data-value="2"></i>
Esta está loca</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO142-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>得到的词元 <code class="literal">esta</code>, <code class="literal">está</code>, <code class="literal">loca</code></p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO142-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>得到的词元 <code class="literal">esta</code>, <code class="literal">esta</code>, <code class="literal">loca</code></p>
</td>
</tr>
</table>
</div>
<p>可以用更多的文档来测试:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT /my_index/my_type/1
{ "title": "Esta loca!" }

PUT /my_index/my_type/2
{ "title": "Está loca!" }</pre>
</div>
<p>现在，我们可以通过联合所有的字段来搜索。在`multi_match`查询中通过 <a class="xref" href="most-fields.html" title="多数字段"><code class="literal">most_fields</code> mode</a> 模式来联合所有字段的结果:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">GET /my_index/_search
{
  "query": {
    "multi_match": {
      "type":     "most_fields",
      "query":    "esta loca",
      "fields": [ "title", "title.folded" ]
    }
  }
}</pre>
</div>
<p>通过 <code class="literal">validate-query</code> API 来执行这个查询可以帮助你理解查询是如何执行的:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">GET /my_index/_validate/query?explain
{
  "query": {
    "multi_match": {
      "type":     "most_fields",
      "query":    "está loca",
      "fields": [ "title", "title.folded" ]
    }
  }
}</pre>
</div>
<p><code class="literal">multi-match</code> 查询会搜索在 <code class="literal">title</code> 字段中原文形式的单词 (<code class="literal">está</code>)，和在 <code class="literal">title.folded</code> 字段中去掉变音符号形式的单词 <code class="literal">esta</code>:</p>
<pre class="literallayout">(title:está        title:loca       )
(title.folded:esta title.folded:loca)</pre>

<p>无论用户搜索的是 <code class="literal">esta</code> 还是 <code class="literal">está</code>; 两个文档都会被匹配，因为去掉变音符号形式的单词在
<code class="literal">title.folded</code> 字段中。然而，只有原文形式的单词在 <code class="literal">title</code> 字段中。此额外匹配会把包含原文形式单词的文档排在结果列表前面。</p>
<p>我们用 <code class="literal">title.folded</code> 字段来 <em>扩大我们的网</em> (<em>widen the net</em>)来匹配更多的文档，然后用原文形式的 <code class="literal">title</code> 字段来把关联度最高的文档排在最前面。在可以为了匹配数量牺牲文本原意的情况下，这个技术可以被用在任何分析器里。</p>
<div class="tip admon">
<div class="icon"></div>
<div class="admon_content">
<p><code class="literal">asciifolding</code> 过滤器有一个叫做 <code class="literal">preserve_original</code> 的选项可以让你这样来做索引，把词的原文词元(original token)和处理—​折叠后的词元(folded token)放在同一个字段的同一个位置。开启了这个选项，结果会像这样:</p>
<pre class="literallayout">Position 1     Position 2
--------------------------
(ésta,esta)    loca
--------------------------</pre>

<p>虽然这个是节约空间的好办法，但是也意味着没有办法再说“给我精确匹配的原文词元”(Give me an exact match on the original word)。包含去掉和不去掉变音符号的词元，会导致不可靠的相关性评分。</p>
<p>所以，正如我们这一章做的，把每个字段的不同形式分开到不同的字段会让索引更清晰。</p>
</div>
</div>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="lowercase-token-filter.html">« 举个例子</a>
</span>
<span class="next">
<a href="unicode-normalization.html">Unicode的世界 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>